#ifndef _DKGL_CAMERA_H_
#define _DKGL_CAMERA_H_

#include "dkglPreRequest.h"
#include "dkglObject.h"
#include "dkglViewport.h"
#include "dkglViewVolume.h"
#include "dkglMovable.h"

#include <assert.h>
#include <memory>


namespace DKGL
{

#if 1// New Camera Class

    class Camera : public Movable
    {
    public:

	    Camera(const String& name);
	
        virtual ~Camera();

	    void look();
	
	    inline void bindViewport(Viewport* viewport)
	    {	
		    assert(viewport && "Viewport is NULL when binding to camera.");
		    _viewport = viewport;	
	    };

	    void addChild(MovablePtr);

	    inline void setNearPlane(float n)
	    {
            _nearPlane = n;
        }


	    inline float getNearPlane(void) const
	    {
            return _nearPlane;
        }


	    inline void setFarPlane(float f)
	    {
            _farPlane = f;
        }


	    inline float getFarPlane(void) const
	    {
            return _farPlane;
        }


	    inline void setFov(float fov)
	    {
            _fov = fov;
        }


	    inline float getFov(void) const
	    {
            return _fov;
        }


	    inline void setProjectionMode(PROJ_MODE mode)
	    { 
            _projectionMode = mode;
        }


	    inline PROJ_MODE getProjectionMode(void) const
	    {
            return _projectionMode;
        }


	    inline void setOrthoWidth(float w)
	    {
            _orthoWidth = w;
        }


	    inline float getOrthoWidth() const
	    {
            return _orthoWidth;
        }


	    inline void setOrthoHeight(float h)
	    {
            _orthoHeight = h;
        }

    private:
	    //virtual void _transformation(){};

	    void _calculateOrthoParams(dbRect2D&);
	
	    Viewport*   _viewport;
	    float       _nearPlane;
	    float       _farPlane;
	    float       _fov;

	    float       _orthoWidth;
	    float       _orthoHeight;

	    bool        _enable;

	    PROJ_MODE   _projectionMode;

	    //std::auto_ptr<ViewVolume> mViewVolume;
    };//Endof Camera Class

	typedef boost::shared_ptr<Camera> CameraPtr;

#else

class Camera : public BaseObject
{
public:
	Camera(const std::string& name = "Unknown Camera");
	~Camera(){};

	void look();
	void look(const Viewport&, bool draw_boarder = false);
	
	inline void bindViewport(Viewport* vp)
	{	
		assert(vp && "Viewport is NULL when binding to camera.");
		mViewport = vp;	
	};

	virtual void pushChild(BaseObject*);

	inline Camera& setNearClipPlane(double n)
	{mNearClipPlane = n; return *this;};

	inline double getNearClipPlane(void) const
	{return mNearClipPlane; };

	inline Camera& setFarClipPlane(double f)
	{mFarClipPlane = f; return *this;};

	inline double getFarClipPlane(void) const
	{return mFarClipPlane;};

	inline Camera& setFov(double fov)
	{mFov = fov; return *this;};

	inline double getFov(void) const
	{return mFov;};

	inline Camera& setProjectionMode(PROJ_MODE mode)
	{ mProjMode = mode; return *this;};

	inline PROJ_MODE getProjectionMode(void) const
	{return mProjMode;};

	inline Camera& setOrthoWidth(float w)
	{
		orthoWidth = w;
		return *this;
	}

	inline float getOrthoWidth() const
	{
		return orthoWidth;
	}

	inline Camera& setOrthoHeight(float h)
	{
		orthoHeight = h;
		return *this;
	}

protected:
	virtual void _transformation(){};

	void _calculateOrthoParams(dbRect2D&);
	
	Viewport *mViewport;
	double mNearClipPlane;
	double mFarClipPlane;
	double mFov;

	float orthoWidth;
	float orthoHeight;

	bool mEnable;

	PROJ_MODE mProjMode;

	std::auto_ptr<ViewVolume> mViewVolume;
};

#endif

}

#endif